{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Numpy\n",
    "Numy, apart from all other features, provides us with the possibility of running our procedures using vectorized operations\n",
    "First let's import numpy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Numpy arrays"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "A1 = np.array([1,4,5,11])  #you should provide a list as the input argument\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 1,  4,  5, 11])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "How to check the data type of an array\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dtype('int32')"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A1.dtype"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "A2 = np.array([1.0,4.2,5.0,11.1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 1. ,  4.2,  5. , 11.1])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dtype('float64')"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A2.dtype"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "listOfNames = [\"benjamin\", \"francesco\", \"rafael\", \"santiago\"]\n",
    "A3 = np.array(listOfNames)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dtype('S9')"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A3.dtype"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dtype('bool')"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A4 = np.array([True, False, True, False])\n",
    "A4.dtype"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So we can see that every numpy array has a unique data type, but what would happen if I give it a list made up of different datatypes !\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "A5 = np.array([5,\"francesco\",1.2 ])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(['5', 'francesco', '1.2'], dtype='|S11')"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It converts all of them into a single datatype !!!!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2.2, 3. , 5. ])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A6= np.array([2.2,3,5])\n",
    "A6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2, 1, 5])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A7 = np.array([2,True, 5])\n",
    "A7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(['jack', '2', 'True', '5'], dtype='|S4')"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A8 = np.array([\"jack\",2,True, 5])\n",
    "A8"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is a huge disadvantage ! and cmmon source of errors !\n",
    "but of course it is an awesome tool for vectorized operation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1.4, 5.3, 7.6, 2.2, 3.0, 9.5]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L9 = [1.4,5.3,7.6]\n",
    "L10 = [2.2,3.0,9.5]\n",
    "L11 = L9+L10\n",
    "L11"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So we saw that lists do not perform vectorized operations! numpy arrays come to help !"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 3.6,  8.3, 17.1])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A9 = np.array(L9)\n",
    "A10=np.array(L10)\n",
    "A11 = A9+ A10\n",
    "A11"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 3.08, 15.9 , 72.2 ])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A12 = A9 - A10\n",
    "A12\n",
    "A13 = A9*A10\n",
    "A13"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For matrix multiplication you should use A.dot(B)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "multiplication with number, The list does not do what we want! we have to use numpy arrays !!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3, 5, 6, 3, 5, 6]"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L14 = [3,5,6]\n",
    "L15 = 2*L14\n",
    "L15"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 6, 10, 12])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A14 = np.array(L14)\n",
    "A15 = 2*A14\n",
    "A15"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "opaque HF Values\n",
      "[10.8624  6.2    44.144 ]\n",
      "the laod of each component\n",
      "[1149.24192 1240.        97.1168 ]\n"
     ]
    }
   ],
   "source": [
    "opaque_item_list = [\"wall\", \"ceiling\", \"door\"]\n",
    "opaque_item_array = np.array(opaque_item_list)\n",
    "opaque_U_array = np.array([0.438,0.25, 1.78])\n",
    "opaque_area_array = np.array([105.8,200,2.2])\n",
    "T_inside_heating = 20\n",
    "T_outside_heating =-4.8 \n",
    "DeltaT_heating = T_inside_heating - T_outside_heating\n",
    "opaque_HF_array  = opaque_U_array*DeltaT_heating\n",
    "opaque_Q_Array = opaque_HF_array*opaque_area_array\n",
    "print(\"opaque HF Values\")\n",
    "print(opaque_HF_array)\n",
    "print(\"the laod of each component\")\n",
    "print(opaque_Q_Array)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1149.24, 1240.  ,   97.12])"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "opaque_Q_Array_rounded = np.round(opaque_Q_Array,2)\n",
    "opaque_Q_Array_rounded"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "How to extract items from numpy arrays "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1240.0"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Q_ceiling = opaque_Q_Array_rounded[1]\n",
    "Q_ceiling\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1149.24, 1240.  ,    0.  ])"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "opaque_Q_Array_rounded[-1] = 0\n",
    "opaque_Q_Array_rounded"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The amazing logical arrays "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False,  True, False])"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "TheONesMoreThan1200 = opaque_Q_Array_rounded > 1200\n",
    "TheONesMoreThan1200"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Remember if you want t o use logial operators on numpy logical arrays you should use & for and , | for or \n",
    "The alternative solution is to use logical_and , logical_or which are numpy function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False, False])"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "TheONesMoreThan1200LessThan1210 =(opaque_Q_Array_rounded > 1200) & (opaque_Q_Array_rounded < 1210) \n",
    "TheONesMoreThan1200LessThan1210"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False, False])"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "TheONesMoreThan1200LessThan1210 =np.logical_and(opaque_Q_Array_rounded > 1200,opaque_Q_Array_rounded < 1210) \n",
    "TheONesMoreThan1200LessThan1210"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False,  True,  True])"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A15 = np.array([3,5,6,11])\n",
    "A16 = A15 > 5\n",
    "A16"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 6, 11])"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A17 = A15[A16]\n",
    "A17"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You could also do this manually\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([11])"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A18 = A15[np.array([False,False,False, True])]\n",
    "A18"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1149.24"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "index_wall_arrray = opaque_item_array == \"wall\"\n",
    "index_wall_arrray\n",
    "Q_wall = opaque_Q_Array_rounded[index_wall_arrray]\n",
    "Q_wall = Q_wall[0]\n",
    "Q_wall"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1149.24"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Q_wall = opaque_Q_Array_rounded[opaque_item_array==\"wall\"][0]\n",
    "Q_wall"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1149.24, 1240.  ])"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Q_wall_ceiling = opaque_Q_Array_rounded[(opaque_item_array ==\"wall\") | (opaque_item_array== \"ceiling\")]\n",
    "Q_wall_ceiling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2486.36"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Q_tot_opaque = opaque_Q_Array.sum()\n",
    "round(Q_tot_opaque,2)\n",
    "Q_avg_opaque = opaque_Q_Array.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [],
   "source": [
    "resistance_names = np.array([\"R_internal\",\"R_foam\",\"R_wood\",\"R_plaster\",\"R_external\"])\n",
    "resistance_types = np.array([\"conv\",\"cond\",\"cond\",\"cond\",\"conv\"])\n",
    "resistance_k = np.array([ None,0.05,0.4,1,None])\n",
    "resistance_L = np.array([ None,0.06,0.1,0.01,None])\n",
    "resistance_A = np.array([ 15,15,15,15,15])\n",
    "resistance_h = np.array([ 8.9,None,None,None,20])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0., 0., 0., 0., 0.])"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "resistance_RValues = np.zeros(5)\n",
    "resistance_RValues"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.08, 0.016666666666666666, 0.0006666666666666666], dtype=object)"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "resistance_L[resistance_types==\"cond\"]/ (resistance_k[resistance_types==\"cond\"]*resistance_A[resistance_types==\"cond\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\behzad\\Anaconda2_\\lib\\site-packages\\ipykernel_launcher.py:1: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.\n",
      "  \"\"\"Entry point for launching an IPython kernel.\n",
      "C:\\Users\\behzad\\Anaconda2_\\lib\\site-packages\\ipykernel_launcher.py:2: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.\n",
      "  \n"
     ]
    }
   ],
   "source": [
    "resistance_RValues[[resistance_types==\"cond\"]]=resistance_L[resistance_types==\"cond\"]/ (resistance_k[resistance_types==\"cond\"]*resistance_A[resistance_types==\"cond\"])\n",
    "resistance_RValues[[resistance_types==\"conv\"]]=1.0/(resistance_h[resistance_types==\"conv\"]* resistance_A[resistance_types==\"conv\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.00749064, 0.08      , 0.01666667, 0.00066667, 0.00333333])"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "resistance_RValues"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.15"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
